package com.econ.powercloud.ems.timing.report;

import com.alibaba.fastjson.JSON;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalDay;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalMonth;
import com.econ.powercloud.clickhouse.entity.EmsStatisticalYear;
import com.econ.powercloud.common.base.facade.util.JacksonUtil;
import com.econ.powercloud.ems.aop.TimingRetryValid;
import com.econ.powercloud.ems.common.enums.*;
import com.econ.powercloud.ems.common.util.DateTimeUtil;
import com.econ.powercloud.ems.common.util.KeepDecimalPointUtil;
import com.econ.powercloud.ems.constant.SysConstant;
import com.econ.powercloud.ems.dal.entity.*;
import com.econ.powercloud.ems.dal.entity.ext.EmsPriceModelDetailExt;
import com.econ.powercloud.ems.service.biz.ClickHouseBizService;
import com.econ.powercloud.ems.service.dao.*;
import com.econ.powercloud.ems.pojo.EmsColumnPidVO;
import com.econ.powercloud.ems.pojo.EmsPriceInfoVO;
import com.econ.powercloud.ems.pojo.InComeCalculationVO;
import com.econ.powercloud.ems.pojo.MeterHisDataVO;
import com.econ.powercloud.ems.timing.report.strategy.IncomeCalculationStrategy;
import com.econ.powercloud.ems.util.RedisCacheUtil;
import com.econ.powercloud.ems.util.TimeUtil;
import com.econ.powercloud.ems.util.WeatherForecastUtil;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 储能装置日报数据统计定时任务
 * 时间紧,暂时先使用前人写的逻辑
 */
@Component
@Slf4j
public class ESDeviceIncomeReportTask {
    private static final Logger logger = LoggerFactory.getLogger(ESDeviceIncomeReportTask.class);
    private static SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    private static final Integer IS_SPECIAL = 1;
    //
    public static final String PRICE_MODEL = "ems-price-model";
    //
    public static final String INCOME_DAY = "ems-income-day";
    //
    public static final String INCOME_MONTH = "ems-income-month";

    @Autowired
    private WeatherForecastUtil weatherForecastUtil;
    @Autowired
    private EmsAreaDAO emsAreaDAO;
    @Autowired
    private EmsModelUseDAO emsModelUseDAO;
    @Autowired
    private EmsDeviceDAO emsDeviceDAO;
    @Autowired
    private EmsColumnConfigDeviceDAO emsColumnConfigDeviceDAO;
    @Autowired
    private RedisCacheUtil redisCacheUtil;
    @Autowired
    private EmsEnergyStationDAO emsEnergyStationDAO;
    @Autowired
    private IncomeCalculationStrategy incomeCalculationStrategy;
    @Autowired
    private EmsPriceModelDetailDAO emsPriceModelDetailDAO;
    @Autowired
    private ClickHouseBizService clickHouseBizService;


    /**
     * 抽出一些补充公共属性的方法
     */
    public void initCommonField(List<EmsStatisticalMonth> statisticalMonths, EmsDevice device){
        if(CollectionUtils.isEmpty(statisticalMonths)){
            return;
        }
        Date nowDate = new Date();
        statisticalMonths.stream().forEach(d->{
            d.setEnergyStationId(device.getEnergyStationId());
            d.setEnergyEquipmentId(device.getEnergyEquipmentId());
            d.setReportId(ReportIdType.INCOME.getCode());
            d.setDeviceCode(device.getDeviceCode());
            d.setGmtCreate(nowDate);
        });
    }

    /**
     * 定时更新后一天的电价模型
     */
    @Scheduled(cron = "0 0 19 * * ?")
    @Transactional(rollbackFor = Throwable.class)
    @TimingRetryValid(lockName = PRICE_MODEL)
    public void updatePriceModel(){
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, +1);
        Date date = calendar.getTime();
        String tomorrow = sdf.format(date);
        //查询当前有效的电价详细设置
        List<EmsPriceModelDetailExt> modelDetailExtList = emsPriceModelDetailDAO.getBaseMapper().selectByTime(date);
        if (CollectionUtils.isEmpty(modelDetailExtList)) {
            logger.info("----------无可用电价详情模型.----------");
            return;
        }
        //存放明日使用的电价模型信息
        List<EmsModelUse> emsModelUseList = Lists.newArrayList();
        //查询所有的市级城市信息
        List<EmsArea> emsAreaList = emsAreaDAO.getCityList();
        //存放城市是否满足温度的特殊条件,key:cityId,value:
        Map<String, Integer> temperSpecialMap = Maps.newHashMap();
        Map<Integer, String> apiIdMap = emsAreaList.stream().collect(Collectors.toMap(EmsArea::getCityCode, EmsArea::getApiId));
        modelDetailExtList.stream().forEach(modelDetailExt -> {
            List<String> cityList = JSON.parseArray("[" + modelDetailExt.getCity() + "]", String.class);
            for (String cityId : cityList) {
                EmsModelUse emsModelUse = EmsModelUse.builder()
                        .dateId(tomorrow)
                        .proviceId(modelDetailExt.getProvince())
                        .cityId(cityId)
                        .voltageLevel(modelDetailExt.getVoltageLevel())
                        .priceType(modelDetailExt.getPriceType())
                        .modelDetailPid(modelDetailExt.getPid())
                        .isSpecial(0)
                        .build();
                //判断是否处于特殊情况
                if (modelDetailExt.getSpecialCase() != null) {
                    if (CaseType.TEMPERATURE.getCode().equals(modelDetailExt.getSpecialCase())) {
                        //先从之前存放的map中获取
                        if (temperSpecialMap.get(cityId) != null) {
                            emsModelUse.setIsSpecial(temperSpecialMap.get(cityId));
                        } else {
                            String apiId = apiIdMap.get(Integer.parseInt(cityId));
                            String tmpMaxNextDay = weatherForecastUtil.getTmpMaxNextDay(apiId);
                            //判断是否满足条件
                            if (judgeConditionType(Double.parseDouble(tmpMaxNextDay), Double.parseDouble(modelDetailExt.getValue()), modelDetailExt.getCompareCond())) {
                                emsModelUse.setIsSpecial(1);
                                temperSpecialMap.put(cityId, 1);
                            } else {
                                temperSpecialMap.put(cityId, 0);
                            }
                        }
                    } else {
                        //其他情况,默认没有特殊情况的存在
                        logger.info(String.format("电价详情id:%s,暂不支持除温度外的其他特殊条件!", modelDetailExt.getPid()));
                    }
                }
                emsModelUseList.add(emsModelUse);
            }
        });
        emsModelUseDAO.deleteByDateId(tomorrow);
        emsModelUseDAO.saveBatch(emsModelUseList);
        logger.info(String.format("更新明日使用电价模型成功,插入%s条记录", emsModelUseList.size()));
    }

    /**
     * 计算前一天的各储能装置电费日报
     */
    @Scheduled(cron = "0 30 0 * * ?")
    @TimingRetryValid(lockName = INCOME_DAY)
    public void calculateIncomeDaily(){
        logger.info("----------开始统计储能装置收益日报----------");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        Date date = calendar.getTime();
        String yesterday = sdf.format(date);
        logger.info(String.format("----------昨日日期：%s---------", yesterday));
        Long startDayTime = TimeUtil.getDayStartTime(date);
        //查询前一天使用电价模型情况
        List<EmsModelUse> emsModelUseList = emsModelUseDAO.selectByTime(yesterday);
        if (CollectionUtils.isEmpty(emsModelUseList)) {
            logger.info("----------无可用电价模型.----------");
            return;
        }
        //key:省份-地市-电压等级-电价类型,value:EmsModelUse
        Map<String, EmsModelUse> emsModelUseMap = emsModelUseList.stream()
                .collect(Collectors.toMap(d -> d.getProviceId() + "-" + d.getCityId() + "-" + d.getVoltageLevel() + "-" + d.getPriceType(), d -> d, (p1, p2) -> p1));
        //查询所有电价详情，并根据pid分类
        List<EmsPriceModelDetail> modelDetails = emsPriceModelDetailDAO.list();
        Map<Integer, EmsPriceModelDetail> modelDetailMap = modelDetails.stream().collect(Collectors.toMap(EmsPriceModelDetail::getPid, d -> d));
        //查询全部计量电表设备
        List<EmsDevice> emsDeviceList = emsDeviceDAO.getListByCondition(null, null, DeviceType.MEASURING_METER.getCode());
        if (CollectionUtils.isEmpty(emsDeviceList)) {
            return;
        }
        //查询电表的尖峰平谷等点号后缀的配置信息
        List<EmsColumnConfigDevice> columnConfigDevices = emsColumnConfigDeviceDAO.list().stream().filter(d -> d.getDitFlag() == 1).collect(Collectors.toList());
        //获取当日零点各时段点号电量数据
        List<EmsColumnPidVO> emsColumnPidVOS = this.getEmsColumnPid(emsDeviceList, columnConfigDevices);
        //第一个key:时间类型(小时,天，月),第二个key:pid
        Map<String, Map<String, MeterHisDataVO>> meterHisDataVOMap = redisCacheUtil.getMeterHisDataByPids(emsColumnPidVOS);
        //获取事件类型为天的数据
        if (MapUtils.isEmpty(meterHisDataVOMap.get(MeterTagType.DAY.getTag()))) {
            logger.info("----------未获取到任何计量电表的0点数据!----------");
            return;
        }
        //key:deviceCode,value:List<MeterHisDataVO>
        Map<String, List<MeterHisDataVO>> epDateMap = meterHisDataVOMap.get(MeterTagType.DAY.getTag()).values()
                .stream().collect(Collectors.groupingBy(d -> d.getDeviceCode()));
        //获取前一日尖峰平谷各时段电量，整理数据
        //        List<EmsStatisticalMonth> emsStatisticalMonths = emsStatisticalMonthDAO.selectByTime(startDayTime, ReportIdType.METER.getCode());
        List<EmsStatisticalDay> emsStatisticals = clickHouseBizService.getDayDataByTimeAndReportId(startDayTime, ReportIdType.METER.getCode());
        List<EmsStatisticalMonth> emsStatisticalMonths = JacksonUtil.convertToList(emsStatisticals, EmsStatisticalMonth.class);
        //第一个key：deviceCode,第二个key：columnId
        Map<String, Map<String, EmsStatisticalMonth>> deviceTimeEpMap = Maps.newHashMap();
        if (CollectionUtils.isNotEmpty(emsStatisticalMonths)) {
            emsStatisticalMonths.stream().collect(Collectors.groupingBy(d -> d.getDeviceCode())).forEach((k, v) -> {
                deviceTimeEpMap.put(k, v.stream().collect(Collectors.toMap(EmsStatisticalMonth::getColumnId, d -> d, (p1, p2) -> p1)));
            });
        }
        //计算电费
        System.out.println("----------开始计算储能装置电费----------");
        //获取储能站的信息，key:储能站id
        Map<String, EmsEnergyStation> stationMap = Maps.newHashMap();
        List<EmsEnergyStation> emsEnergyStations = emsEnergyStationDAO.list();
        if (CollectionUtils.isNotEmpty(emsEnergyStations)) {
            stationMap.putAll(emsEnergyStations.stream().collect(Collectors.toMap(EmsEnergyStation::getEnergyStationId, s -> s)));
        }
        //收益报表需要入库的数据
        List<EmsStatisticalMonth> dataList = Lists.newArrayList();
        //处理单个设备的收益数据
        for (EmsDevice emsDevice : emsDeviceList) {
            //获取需要计算单个电表收益的数据
            List<MeterHisDataVO> meterHisDataVOList = epDateMap.get(emsDevice.getDeviceCode());
            if (CollectionUtils.isEmpty(meterHisDataVOList)) {
                logger.info(String.format("----------设备code:%s,无0点断面数据,无法计算电费。----------", emsDevice.getDeviceCode()));
                continue;
            }
            Map<String, EmsStatisticalMonth> timeEpMap = deviceTimeEpMap.get(emsDevice.getDeviceCode());
            if (MapUtils.isEmpty(timeEpMap)) {
                logger.info(String.format("----------设备code:%s,无昨天计量电表数据,无法计算电费。----------", emsDevice.getDeviceCode()));
                continue;
            }
            EmsEnergyStation station = stationMap.get(emsDevice.getEnergyStationId());
            EmsModelUse emsModelUse = emsModelUseMap.get(station.getProvince() + "-" + station.getCity() + "-" + station.getVoltageLevel() + "-" + station.getPriceType());
            if (emsModelUse == null) {
                logger.info(String.format("----------设备code:%s,无可使用的电价模型,无法计算电费。----------", emsDevice.getDeviceCode()));
                continue;
            }
            EmsPriceInfoVO emsPriceInfoVO = null;
            EmsPriceModelDetail emsPriceModelDetail = modelDetailMap.get(emsModelUse.getModelDetailPid());
            if (Objects.equals(emsModelUse.getIsSpecial(), IS_SPECIAL)) {
                emsPriceInfoVO = EmsPriceInfoVO.builder()
                        .incomeCalculationType(emsPriceModelDetail.getSpecialCalculationType())
                        .spikePrice(emsPriceModelDetail.getSpecialSpikePrice()).peakPrice(emsPriceModelDetail.getSpecialPeakPrice())
                        .flatPrice(emsPriceModelDetail.getSpecialFlatPrice()).valleyPrice(emsPriceModelDetail.getSpecialValleyPrice())
                        .build();
            } else {
                emsPriceInfoVO = EmsPriceInfoVO.builder()
                        .incomeCalculationType(emsPriceModelDetail.getCalculationType())
                        .spikePrice(emsPriceModelDetail.getSpikePrice()).peakPrice(emsPriceModelDetail.getPeakPrice())
                        .flatPrice(emsPriceModelDetail.getFlatPrice()).valleyPrice(emsPriceModelDetail.getValleyPrice())
                        .build();
            }
            List<EmsStatisticalMonth> singleData = this.dealWithSingleMeterData(emsDevice, meterHisDataVOList, stationMap, emsPriceInfoVO, timeEpMap, startDayTime);
            if (CollectionUtils.isNotEmpty(singleData)) {
                dataList.addAll(singleData);
            }
        }
        if (CollectionUtils.isNotEmpty(dataList)) {
            //            emsStatisticalMonthDAO.deleteByTimeAndReportId(startDayTime, ReportIdType.INCOME.getCode());
            clickHouseBizService.deleteMonthDataByTime(startDayTime, ReportIdType.INCOME.getCode());
            //            emsStatisticalMonthDAO.insertBatch(dataList);
            clickHouseBizService.emsStatisticalMonthListDataIntoClickHouse(dataList);
            List<EmsStatisticalMonth> stationDataList = this.getStationDatas(startDayTime, stationMap, dataList);
            //            emsStatisticalMonthDAO.insertBatch(stationDataList);
            clickHouseBizService.emsStatisticalMonthListDataIntoClickHouse(stationDataList);
        }
    }

    /**
     * 处理单个电表的收益数据
     * @param emsDevice : 电表设备
     * @param meterHisDataVOList : 电表设备在0时的电量断面数据
     * @param stationMap : 储能站map,key:储能站id
     * @param emsPriceInfoVO : 尖峰平谷电价VO
     * @param timeEpMap : 这个电表设备有功/无功尖峰平谷的计量电表统计数据
     */
    private List<EmsStatisticalMonth> dealWithSingleMeterData(EmsDevice emsDevice, List<MeterHisDataVO> meterHisDataVOList,
                                                              Map<String, EmsEnergyStation> stationMap, EmsPriceInfoVO emsPriceInfoVO,
                                                              Map<String, EmsStatisticalMonth> timeEpMap, Long startDayTime){
        EmsEnergyStation station = stationMap.get(emsDevice.getEnergyStationId());
        //这个是用来存放收益报表中的字段对应的值，key:columnId,value：值
        Map<String,Double> dataMap = Maps.newHashMap();
        List<EmsStatisticalMonth> dataList = Lists.newArrayList();
        for(MeterHisDataVO meterHisDataVO : meterHisDataVOList){
            //使用策略模式计算数据
            InComeCalculationVO calculationVO = incomeCalculationStrategy.calculation(emsPriceInfoVO.getIncomeCalculationType(),meterHisDataVO,
                    timeEpMap,emsDevice,emsPriceInfoVO,startDayTime);
            if(calculationVO == null){
                continue;
            }
            if(CollectionUtils.isNotEmpty(calculationVO.getStatisticalMonthList())){
                dataList.addAll(calculationVO.getStatisticalMonthList());
            }
            if(MapUtils.isNotEmpty(calculationVO.getDataMap())){
                dataMap.putAll(calculationVO.getDataMap());
            }
        }
        //计算 充用电 和 放电 电费总计
        Double epptFee = dataMap.get(ConfigColumnEnums.EPP1.getCode())+dataMap.get(ConfigColumnEnums.EPP2.getCode())
                +dataMap.get(ConfigColumnEnums.EPP3.getCode())+dataMap.get(ConfigColumnEnums.EPP4.getCode());
        Double enptFee = dataMap.get(ConfigColumnEnums.ENP1.getCode())+dataMap.get(ConfigColumnEnums.ENP2.getCode())
                +dataMap.get(ConfigColumnEnums.ENP3.getCode())+dataMap.get(ConfigColumnEnums.ENP4.getCode());
        //添加充/用电电费总计
        dataList.add(EmsStatisticalMonth.builder()
                .columnId(ConfigColumnEnums.CHARGEFEE.getCode())
                .val(KeepDecimalPointUtil.keepTwoPoint(epptFee))
                .time(startDayTime)
                .build());
        //放电电费总计
        dataList.add(EmsStatisticalMonth.builder()
                .columnId(ConfigColumnEnums.DISCHARGEFEE.getCode())
                .val(KeepDecimalPointUtil.keepTwoPoint(enptFee))
                .time(startDayTime)
                .build());
        //本期节约费用
        dataList.add(EmsStatisticalMonth.builder()
                .columnId(ConfigColumnEnums.SAVEFEE.getCode())
                .val(KeepDecimalPointUtil.keepTwoPoint(enptFee-epptFee))
                .time(startDayTime)
                .build());
        //分享比例
        dataList.add(EmsStatisticalMonth.builder()
                .columnId(ConfigColumnEnums.SHARERATIO.getCode())
                .val(KeepDecimalPointUtil.keepTwoPoint(station.getShareRatio()*100)+"%")
                .time(startDayTime)
                .build());
        //本期节约费用乙方分享金额
        dataList.add(EmsStatisticalMonth.builder()
                .columnId(ConfigColumnEnums.SHAREFEE.getCode())
                .val(KeepDecimalPointUtil.keepTwoPoint((enptFee-epptFee)*station.getShareRatio()))
                .time(startDayTime)
                .build());
        this.initCommonField(dataList,emsDevice);
        return dataList;
    }

    /**
     * 处理储能站日报表
     * @param startDayTime
     * @param stationMap
     * @param emsStatisticalMonthList
     * @return
     */
    private List<EmsStatisticalMonth> getStationDatas(Long startDayTime, Map<String, EmsEnergyStation> stationMap, List<EmsStatisticalMonth> emsStatisticalMonthList) {
        List<EmsStatisticalMonth> resultList = Lists.newArrayList();
        Date nowDate = new Date();
        Map<String, List<EmsStatisticalMonth>> stationDataMap = emsStatisticalMonthList.stream().collect(Collectors.groupingBy(s->s.getEnergyStationId()));
        stationMap.forEach((k,v)->{
            List<EmsStatisticalMonth> emsStatisticalMonths = stationDataMap.get(k);
            if(CollectionUtils.isNotEmpty(emsStatisticalMonths)){
                Map<String,List<EmsStatisticalMonth>> columnDataMap = emsStatisticalMonths.stream().collect(Collectors.groupingBy(c->c.getColumnId()));
                for(ConfigColumnEnums configColumn : ConfigColumnEnums.values()){
                    if(configColumn.getCode().equals(ConfigColumnEnums.SHARERATIO.getCode()) || configColumn.getCode().equals(ConfigColumnEnums.SHAREFEE.getCode())){
                        continue;
                    }
                    List<EmsStatisticalMonth> dataList = columnDataMap.get(configColumn.getCode());
                    double stationVal = 0.0;
                    if(null!=dataList){
                        for(EmsStatisticalMonth data : dataList){
                            double val = Double.parseDouble(data.getVal()==null?"0.0":data.getVal());
                            stationVal += val;
                        }
                    }
                    resultList.add(EmsStatisticalMonth.builder()
                            .energyStationId(k)
                            .reportId(ReportIdType.INCOME.getCode())
                            .columnId(configColumn.getCode())
                            .val(KeepDecimalPointUtil.keepTwoPoint(stationVal))
                            .time(startDayTime)
                            .gmtCreate(nowDate)
                            .build());
                }
            }
        });
        return resultList;
    }

    /**
     * 计算前一天的储能站及装置的收益月报
     */
    @Scheduled(cron = "0 0 1 * * ?")
    @TimingRetryValid(lockName = INCOME_MONTH)
    public Integer calculateIncomeMonthly(){
        System.out.println("----------开始统计收益月报----------");
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE, -1);
        Date date = calendar.getTime();
        Long startDayTime = DateTimeUtil.getStartOfDay(date);
        Long startMonthTime = DateTimeUtil.getStartOfMonth(date);
        Long now = System.currentTimeMillis();
        Date nowDate = new Date(now);
        List<EmsStatisticalYear> resultList = Lists.newArrayList();
        //统计储能装置月数据
        //        List<EmsStatisticalMonth> deviceDataList = emsStatisticalMonthDAO.getBaseMapper().selectDeviceDatasByTimes(startMonthTime,startDayTime, ReportIdType.INCOME.getCode());
        List<EmsStatisticalMonth> deviceDataList = clickHouseBizService.selectDeviceDatasByTimes(startMonthTime, startDayTime, ReportIdType.INCOME.getCode());
        Map<String, List<EmsStatisticalMonth>> deviceDataMap = deviceDataList.stream().collect(Collectors.groupingBy(d -> d.getDeviceCode()));
        List<EmsDevice> emsDeviceList = emsDeviceDAO.list();
        Map<String, EmsDevice> deviceMap = emsDeviceList.stream().collect(Collectors.toMap(EmsDevice::getDeviceCode, d -> d));
        DecimalFormat df = new DecimalFormat("#.##");
        deviceDataMap.forEach((k, v) -> {
            EmsDevice emsDevice = deviceMap.get(k);
            Map<String, List<EmsStatisticalMonth>> columnDataMap = v.stream().collect(Collectors.groupingBy(c -> c.getColumnId()));
            for (ConfigColumnEnums configColumn : ConfigColumnEnums.values()) {
                if (configColumn.getCode().equals(ConfigColumnEnums.SHARERATIO.getCode()) || configColumn.getCode().equals(ConfigColumnEnums.SHAREFEE.getCode())) {
                    continue;
                }
                List<EmsStatisticalMonth> dataList = columnDataMap.get(configColumn.getCode());
                double deviceVal = 0.0;
                if (null != dataList) {
                    for (EmsStatisticalMonth data : dataList) {
                        double val = Double.parseDouble(data.getVal() == null ? "0.0" : data.getVal());
                        deviceVal += val;
                    }
                }
                resultList.add(EmsStatisticalYear.builder()
                        .energyStationId(emsDevice == null ? "未知电站" : emsDevice.getEnergyStationId())
                        .energyEquipmentId(emsDevice == null ? "未知装置" : emsDevice.getEnergyEquipmentId())
                        .reportId(ReportIdType.INCOME.getCode())
                        .deviceCode(k)
                        .columnId(configColumn.getCode())
                        .val(df.format(deviceVal))
                        .time(startMonthTime)
                        .gmtCreate(nowDate)
                        .build());
            }
        });

        //统计储能站月数据
        Map<String, List<EmsStatisticalMonth>> stationDataMap = deviceDataList.stream().collect(Collectors.groupingBy(d -> d.getEnergyStationId()));
        stationDataMap.forEach((k, v) -> {
            Map<String, List<EmsStatisticalMonth>> columnDataMap = v.stream().collect(Collectors.groupingBy(c -> c.getColumnId()));
            for (ConfigColumnEnums configColumn : ConfigColumnEnums.values()) {
                if (configColumn.getCode().equals(ConfigColumnEnums.SHARERATIO.getCode()) || configColumn.getCode().equals(ConfigColumnEnums.SHAREFEE.getCode())) {
                    continue;
                }
                List<EmsStatisticalMonth> dataList = columnDataMap.get(configColumn.getCode());
                double stationVal = 0.0;
                if (null != dataList) {
                    for (EmsStatisticalMonth data : dataList) {
                        double val = Double.parseDouble(data.getVal() == null ? "0.0" : data.getVal());
                        stationVal += val;
                    }
                }
                resultList.add(EmsStatisticalYear.builder()
                        .energyStationId(k)
                        .reportId(ReportIdType.INCOME.getCode())
                        .columnId(configColumn.getCode())
                        .val(df.format(stationVal))
                        .time(startMonthTime)
                        .gmtCreate(nowDate)
                        .build());
            }
        });
        int res = resultList.size();
        if (CollectionUtils.isNotEmpty(resultList)) {
            //            emsStatisticalYearDAO.deleteByTimeAndReportId(startMonthTime, ReportIdType.INCOME.getCode());
            clickHouseBizService.deleteYearDataByTime(startMonthTime, ReportIdType.INCOME.getCode());
            //            res = emsStatisticalYearDAO.insertBatch(resultList);
            clickHouseBizService.emsStatisticalYearListDataIntoClickHouse(resultList);
            System.out.println("----------成功插入" + res + "条记录----------");
        }
        return res;
    }

    /**
     * 根据条件的类型,判断是否满足条件(大于小于等于等)
     * @param beforeNum : 判断条件前面的数值
     * @param afterNum : 判断条件后面的数值
     * @param conditionType : ConditionType枚举中对应code
     */
    private boolean judgeConditionType(Double beforeNum,Double afterNum,Integer conditionType){
        ConditionType type = ConditionType.fromCode(conditionType);
        switch (type){
            case GT:
                return beforeNum > afterNum;
            case LT:
                return beforeNum < afterNum;
            case EQUAL:
                return beforeNum.equals(afterNum);
            case GTE:
                return beforeNum >= afterNum;
            case LTE:
                return beforeNum <= afterNum;
            default:
                //如果上述判断没有一个满足,返回false
                return false;
        }
    }

    /**
     * 整理设备点号数据
     * @param emsDeviceList
     * @param columnConfigDevices
     * @return
     */
    private List<EmsColumnPidVO> getEmsColumnPid(List<EmsDevice> emsDeviceList, List<EmsColumnConfigDevice> columnConfigDevices) {
        if(CollectionUtils.isEmpty(emsDeviceList) || CollectionUtils.isEmpty(columnConfigDevices)){
            return Collections.emptyList();
        }
        List<EmsColumnPidVO> emsColumnPidVOS = Lists.newArrayList();
        emsDeviceList.stream().forEach(device->{
            columnConfigDevices.stream().forEach(config->{
                emsColumnPidVOS.add(EmsColumnPidVO.builder()
                        .columnId(config.getColumnId()).deviceCode(device.getDeviceCode())
                        .initDeviceCode(device.getInitDeviceCode())
                        .dit(config.getColumnId())
                        .pid(device.getInitDeviceCode() + SysConstant.SPOT + config.getColumnId())
                        .build());
            });
        });
        return emsColumnPidVOS;
    }
}
